using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

// TODO: replace these with the processor input and output types.
using TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent;
using TOutput = Microsoft.Xna.Framework.Content.Pipeline.Processors.ModelContent;

namespace BoundingBoxModelPipelineExtension
{
    /// <summary>
    /// This class will be instantiated by the XNA Framework Content Pipeline
    /// to apply custom processing to content data, converting an object of
    /// type TInput to TOutput. The input and output types may be the same if
    /// the processor wishes to alter data without changing its type.
    ///
    /// This should be part of a Content Pipeline Extension Library project.
    ///
    /// TODO: change the ContentProcessor attribute to specify the correct
    /// display name for this processor.
    /// </summary>
    [ContentProcessor(DisplayName = "BoundingBoxModelPipeline")]
    public class ContentProcessor1 : ModelProcessor
    {
        float minX = float.MaxValue;
        float minY = float.MaxValue;
        float minZ = float.MaxValue;
        float maxX = float.MinValue;
        float maxY = float.MinValue;
        float maxZ = float.MinValue;

        public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            ModelContent modelContent = base.Process(input, context);
            Parse(input as MeshContent);
            
            modelContent.Tag = new BoundingBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ));
            return modelContent;
        }

        private void Parse(MeshContent content)
        {
            foreach (Vector3 vector in content.Positions)
            {
                if (vector.X < minX)
                    minX = vector.X;

                if (vector.Y < minY)
                    minY = vector.Y;

                if (vector.Z < minZ)
                    minZ = vector.Z;

                if (vector.X > maxX)
                    maxX = vector.X;

                if (vector.Y > maxY)
                    maxY = vector.Y;

                if (vector.Z > maxZ)
                    maxZ = vector.Z;
            }
        }
    }
}